Package org.python.pydev.compare

Source Code of org.python.pydev.compare.PyMergeViewer

/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.compare;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.IResourceProvider;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.python.pydev.core.IIndentPrefs;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.core.IPythonPartitions;
import org.python.pydev.core.MisconfigurationException;
import org.python.pydev.core.docutils.PyPartitionScanner;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.editor.IPySyntaxHighlightingAndCodeCompletionEditor;
import org.python.pydev.editor.PyEdit;
import org.python.pydev.editor.PyEditConfiguration;
import org.python.pydev.editor.PyEditConfigurationWithoutEditor;
import org.python.pydev.editor.actions.FirstCharAction;
import org.python.pydev.editor.actions.PyAction;
import org.python.pydev.editor.actions.PyBackspace;
import org.python.pydev.editor.actions.PyPeerLinker;
import org.python.pydev.editor.autoedit.DefaultIndentPrefs;
import org.python.pydev.plugin.nature.PythonNature;
import org.python.pydev.plugin.preferences.PydevPrefs;
import org.python.pydev.ui.ColorAndStyleCache;

/**
* Provides a viewer that provides:
* - syntax highlighting
* - indent strategy
* - proper backspace
* - code completion
*/
public class PyMergeViewer extends TextMergeViewer {

    private List<ColorAndStyleCache> colorCache;
    private List<IPropertyChangeListener> prefChangeListeners;

    public PyMergeViewer(Composite parent, int style, CompareConfiguration configuration) {
        super(parent, style | SWT.LEFT_TO_RIGHT, configuration);
    }

    @Override
    protected IDocumentPartitioner getDocumentPartitioner() {
        return PyPartitionScanner.createPyPartitioner();
    }

    /**
     * Overridden to handle the partitioning (will only work on Eclipse 3.3)
     */
    @Override
    protected String getDocumentPartitioning() {
        return IPythonPartitions.PYTHON_PARTITION_TYPE;
    }

    private IPythonNature getPythonNature(Object compareInput) {
        IResource resource = getResource(compareInput);
        if (resource != null) {
            return PythonNature.getPythonNature(resource);
        }
        return null;

    }

    private IResource getResource(Object compareInput) {
        if (!(compareInput instanceof ICompareInput)) {
            return null;
        }
        ICompareInput input = (ICompareInput) compareInput;
        if (input == null) {
            return null;
        }

        IResourceProvider rp = null;
        ITypedElement te = input.getLeft();

        if (te instanceof IResourceProvider) {
            rp = (IResourceProvider) te;
        }

        if (rp == null) {
            te = input.getRight();
            if (te instanceof IResourceProvider) {
                rp = (IResourceProvider) te;
            }
        }

        if (rp == null) {
            te = input.getAncestor();
            if (te instanceof IResourceProvider) {
                rp = (IResourceProvider) te;
            }
        }
        if (rp != null) {
            return rp.getResource();
        }
        return null;
    }

    /**
     * Overridden to handle backspace (will only be called on Eclipse 3.5)
     */
    @Override
    protected SourceViewer createSourceViewer(Composite parent, int textOrientation) {
        final SourceViewer viewer = super.createSourceViewer(parent, textOrientation);
        viewer.appendVerifyKeyListener(PyPeerLinker.createVerifyKeyListener(viewer));
        viewer.appendVerifyKeyListener(PyBackspace.createVerifyKeyListener(viewer, null));
        IWorkbenchPart workbenchPart = getCompareConfiguration().getContainer().getWorkbenchPart();

        //Note that any site should be OK as it's just to know if a keybinding is active.
        IWorkbenchPartSite site = null;
        if (workbenchPart != null) {
            site = workbenchPart.getSite();
        } else {
            IWorkbenchWindow window = PyAction.getActiveWorkbenchWindow();
            if (window != null) {
                IWorkbenchPage activePage = window.getActivePage();
                if (activePage != null) {
                    IWorkbenchPart activePart = activePage.getActivePart();
                    if (activePart != null) {
                        site = activePart.getSite();
                    }
                }
            }
        }
        VerifyKeyListener createVerifyKeyListener = FirstCharAction.createVerifyKeyListener(viewer, site, true);
        if (createVerifyKeyListener != null) {
            viewer.appendVerifyKeyListener(createVerifyKeyListener);
        }
        return viewer;
    }

    private List<ColorAndStyleCache> getColorCache() {
        if (this.colorCache == null) {
            this.colorCache = new ArrayList<ColorAndStyleCache>();
        }
        return this.colorCache;
    }

    public List<IPropertyChangeListener> getPrefChangeListeners() {
        if (this.prefChangeListeners == null) {
            this.prefChangeListeners = new ArrayList<IPropertyChangeListener>();
        }
        return this.prefChangeListeners;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void configureTextViewer(TextViewer textViewer) {
        if (!(textViewer instanceof SourceViewer))
            return;
        final SourceViewer sourceViewer = (SourceViewer) textViewer;

        final IIndentPrefs indentPrefs = new DefaultIndentPrefs();

        //Hack to provide the source viewer configuration that'll only be created later (there's a cycle there).
        final WeakReference<PyEditConfigurationWithoutEditor>[] sourceViewerConfigurationObj = new WeakReference[1];

        IPreferenceStore chainedPrefStore = PydevPrefs.getChainedPrefStore();
        final ColorAndStyleCache c = new ColorAndStyleCache(chainedPrefStore);
        this.getColorCache().add(c); //add for it to be disposed later.

        IPySyntaxHighlightingAndCodeCompletionEditor editor = new IPySyntaxHighlightingAndCodeCompletionEditor() {

            public void resetForceTabs() {

            }

            public void resetIndentPrefixes() {
                SourceViewerConfiguration configuration = getEditConfiguration();
                String[] types = configuration.getConfiguredContentTypes(sourceViewer);
                for (int i = 0; i < types.length; i++) {
                    String[] prefixes = configuration.getIndentPrefixes(sourceViewer, types[i]);
                    if (prefixes != null && prefixes.length > 0)
                        sourceViewer.setIndentPrefixes(prefixes, types[i]);
                }
            }

            public IIndentPrefs getIndentPrefs() {
                return indentPrefs;
            }

            public ISourceViewer getEditorSourceViewer() {
                return sourceViewer;
            }

            public PyEditConfigurationWithoutEditor getEditConfiguration() {
                return sourceViewerConfigurationObj[0].get();
            }

            public ColorAndStyleCache getColorCache() {
                return c;
            }

            public PySelection createPySelection() {
                ISelection selection = sourceViewer.getSelection();
                if (selection instanceof ITextSelection) {
                    return new PySelection(sourceViewer.getDocument(), (ITextSelection) selection);
                } else {
                    return null;
                }
            }

            public File getEditorFile() {
                IResource file = PyMergeViewer.this.getResource(PyMergeViewer.this.getInput());
                if (file != null && file instanceof IFile) {
                    IPath path = file.getLocation().makeAbsolute();
                    return path.toFile();
                }
                return null;
            }

            public IPythonNature getPythonNature() throws MisconfigurationException {
                return PyMergeViewer.this.getPythonNature(PyMergeViewer.this.getInput());
            }

            public Object getAdapter(Class adapter) {
                if (adapter == IResource.class) {
                    return PyMergeViewer.this.getResource(PyMergeViewer.this.getInput());
                }
                if (adapter == IFile.class) {
                    IResource resource = PyMergeViewer.this.getResource(PyMergeViewer.this.getInput());
                    if (resource instanceof IFile) {
                        return resource;
                    }
                }
                return null;
            }
        };

        final PyEditConfiguration sourceViewerConfiguration = new PyEditConfiguration(c, editor, chainedPrefStore);
        sourceViewerConfigurationObj[0] = new WeakReference<PyEditConfigurationWithoutEditor>(sourceViewerConfiguration);
        sourceViewer.configure(sourceViewerConfiguration);

        IPropertyChangeListener prefChangeListener = PyEdit.createPrefChangeListener(editor);
        getPrefChangeListeners().add(prefChangeListener);
        chainedPrefStore.addPropertyChangeListener(prefChangeListener);
    }

    @Override
    protected void handleDispose(DisposeEvent event) {
        super.handleDispose(event);

        List<ColorAndStyleCache> colorCache = getColorCache();
        for (ColorAndStyleCache c : colorCache) {
            c.dispose();
        }
        colorCache.clear();

        List<IPropertyChangeListener> prefChangeListeners = getPrefChangeListeners();
        for (IPropertyChangeListener l : prefChangeListeners) {
            PydevPrefs.getChainedPrefStore().removePropertyChangeListener(l);
        }
        prefChangeListeners.clear();
    }

}
TOP

Related Classes of org.python.pydev.compare.PyMergeViewer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.